package util;

import util.parser.BinaryTree;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Vector;

import static util.GameHandler.*;

public class Util {
    public static final int FAC[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};

    /**
     * 利用优化的确定性搜索方法，并对搜索结果进行去重(不必排序)
     *
     * @param arr
     * @return
     */
    public static Set<String> searchAll(int[] arr) {
        Set<String> lists = new HashSet<>();
        for (int cc = 0; cc < FAC[4]; cc++) {
            int[] idx = codel(cc, 4);
            String a = String.valueOf(arr[idx[0]]);
            String b = String.valueOf(arr[idx[1]]);
            String c = String.valueOf(arr[idx[2]]);
            String d = String.valueOf(arr[idx[3]]);
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                    for (int k = 0; k < 4; k++) {
                        String X = OPERATORS[i];
                        String Y = OPERATORS[j];
                        String Z = OPERATORS[k];
                        for (String[] ee : new String[][]{
                                {a, b, X, c, Y, d, Z},
                                {a, b, c, X, Y, d, Z},
                                {a, b, X, c, d, Y, Z},
                                {a, b, c, X, d, Y, Z},
                                {a, b, c, d, X, Y, Z},}) {
                            if (Math.abs(Evaluator.eval(Arrays.asList(ee)) - TARGET) < EPS) {
                                BinaryTree tree = BinaryTree.createBinaryTree(new Vector(Arrays.asList(ee)));
                                StringBuffer buffer = new StringBuffer();
                                tree.midVisit(buffer);
                                lists.add(buffer.toString());
                            }
                        }
                    }
        }
        return lists;
    }

    public static int[] codel(int x, int m) {//next_permutation()
        int[] label = new int[m];
        int[] n = new int[m];
        int cnt;
        for (int i = 0; i < m; i++)
            label[i] = 1;
        for (int i = 0; i < m; i++) {
            cnt = x / FAC[m - 1 - i];
            x = x % FAC[m - 1 - i];
            for (int j = 0; j < m; j++) {
                if (label[j] == 0)
                    continue;
                if (cnt == 0) {
                    label[j] = 0;
                    n[i] = j;
                    break;
                }
                cnt--;
            }
        }
        return n;
    }
}
